
/*
 * config3.c
*/

#include "config3.h"
#include "lfs/lfs_config.h"
#include "log/log2.h"
#include "utility/SoftCRC.h"
#include "BSP.h"
#include "mbedtls/aes.h"
#include "mbedtls/cmac.h"
#include "Reader/reader_samav3.h"
#include "FreeRTOS.h"
#include "task.h"

#pragma pack(1)

typedef struct {    
    uint8_t uid[8];
}config_sam_t;

#pragma pack()

#define CFG_VER_KEY     0x0002
#define CFG_VER_PARAM   0x0002
#define CFG_VER_SAM     0x0001

// 定义密钥文件名
#define FILE_NAME_KEY  "key"      //密钥文件名
#define FILE_NAME_PARAM  "param"
#define FILE_NAME_SAM   "sam"

#define CFG_KEY_ENC_SIZE        (sizeof(config_key_t)+16)
#define CFG_KEY_ENC_MAC_SIZE    (sizeof(config_key_t)+sizeof(config_storage_t)+32)

// 声明密钥文件名的常量字符串
static const char key_file_name[] = FILE_NAME_KEY;
static const char param_file_name[] = FILE_NAME_PARAM;
static const char sam_file_name[] = FILE_NAME_SAM;

static const uint16_t config_key_magic = 0x4B45; // "KY" in ASCII
static const uint16_t config_param_magic = 0x5052; // "PR" in ASCII
static const uint16_t config_sam_magic = 0x5345; // "SE" in ASCII

//3B5949E0C26B87767A4752A276DE9570
static const uint8_t root_key[16] = { 0x3B, 0x59, 0x49, 0xE0, 0xC2, 0x6B, 0x87, 0x76, 0x7A, 0x47, 0x52, 0xA2, 0x76, 0xDE, 0x95, 0x70 };
static uint8_t store_key[16];
static uint8_t sam_uid[8] = {0};
static const uint8_t sam_uid_default[8] = {0};
// 工厂默认密钥
static const key_t factory_keys[3] = {
    [0] = {
      .id = KID_KFR0,       // 密钥ID
      .ver = 0x01,          // 密钥版本
      .type = KEY_T_AES128,   // 密钥类型
      .data = {
            0xD2,0x22,0x9A,0xC0,0xF6,0x9F,0xC8,0x4E,
            0x87,0x4F,0x2F,0x88,0xD5,0x52,0x5B,0xA6
        },
    },

    [1] = {
        .id = KID_KFR,       // 密钥ID
        .ver = 0x01,          // 密钥版本
        .type = KEY_T_AES128,   // 密钥类型
        .data = {
            0xBF,0x84,0xB0,0xCC,0x39,0xD6,0xE1,0x53,
            0xE6,0x76,0x06,0xAF,0x46,0x5C,0x66,0x81
        },
    },

    [2] = {
       .id = KID_KFM,       // 密钥ID
       .ver = 0x01,          // 密钥版本
       .type = KEY_T_AES128,   // 密钥类型
       .data = {
            0x35,0x55,0x98,0x72,0x35,0xAA,0x4D,0xFB,
            0xF4,0xD8,0x35,0xC0,0x45,0xDF,0xDB,0x98
        }, 
   }    
};
static const uint8_t keys[2][16] = {
	[0] = {
		0x76, 0x76, 0x09, 0xED, 0x97, 0x33, 0xAF, 0x6C,
		0x20, 0x74, 0x62, 0x30, 0xFB, 0x03, 0x7D, 0x19
	},

	[1] = {
		0xB8, 0x58, 0xAB, 0x3A, 0xEA, 0x17, 0x2C, 0xFD,
		0x47, 0xBE, 0xDE, 0x63, 0xE8, 0x33, 0x52, 0x0A
	}
};
/*默认密钥*/
const config_key_t cfg_key_default = {
    .apple_keys = {
        [0] = {
            .id = KID_APPLE_PRIV,       // 密钥ID
            .ver = 0x01,          // 密钥版本
            .type = KEY_T_3DES,   // 密钥类型
            .data = {
                    0x30, 0x84, 0x5e, 0xf6, 0x5b, 0x17, 0x25, 0x20, 
					0xb7, 0x57, 0x36, 0x01, 0x2c, 0x24, 0xd1, 0x16
                },
        },
        [1] = {
            .id = KID_APPLE_CRED,       // 密钥ID
            .ver = 0x01,          // 密钥版本
            .type = KEY_T_AES128,   // 密钥类型
            .data = {
                    0xab, 0x43, 0x7c, 0xb9, 0xf5, 0x9c, 0xb8, 0x19, 
					0xf6, 0x70, 0x9d, 0xc1, 0x8f, 0xea, 0xf0, 0xb4
                }, 

        },
    },
    .google_key = {
            .id = KID_GOOGLE,       // 密钥ID
            .ver = 0x01,          // 密钥版本
            .type = KEY_T_AES128,   // 密钥类型
            .data = {
                0xD4,0x28,0x31,0xB1,0x16,0x43,0x68,0x44,
                0xD5,0xAE,0xD5,0x67,0xB1,0xDA,0x14,0xE2
            },
    },
    .leaf_key = {
            .id = KID_LEAF,       // 密钥ID
            .ver = 0x01,          // 密钥版本
            .type = KEY_T_AES128,   // 密钥类型
            .data = {
                0xDB,0x01,0x01,0x01,
                0x01,0x01,0x01,0x01,
                0x01,0x01,0x01,0x01,
                0x01,0x01,0x01,0x01
            },
    },
    .samsung_pay_key = {
            .id = KID_SAMSUNG_PAY,       // 密钥ID
            .ver = 0x01,          // 密钥版本
            .type = KEY_T_AES128,   // 密钥类型
            .data = {
                0xc0,0x50,0xb8,0xd4,0x79,0x86,0xad,0x81,
                0x43,0xc8,0x52,0x5c,0x28,0xa7,0xbf,0x74
            },
    },
    .swiftlane_awc_app = {
            .id = KID_SW_AWC_APP,       // 密钥ID
            .ver = 0x01,          // 密钥版本
            .type = KEY_T_AES128,   // 密钥类型
            .data = {
                0x39,0x94,0x9D,0x07,0xA5,0x73,0xE6,0x69,
                0x20,0xA0,0x82,0xBA,0xBB,0x58,0xC1,0x79
            },
    },
    .swiftlane_sdc_read = {
            .id = KID_SW_SDC_READ,       // 密钥ID
            .ver = 0x01,          // 密钥版本
            .type = KEY_T_AES128,   // 密钥类型
            .data = {
                //48C9DEC5BD43F1C03D2AC37B09842951
                0x48,0xC9,0xDE,0xC5,0xBD,0x43,0xF1,0xC0,
                0x3D,0x2A,0xC3,0x7B,0x09,0x84,0x29,0x51
            },
    },
    .access_grid_apple_privacy = {
        .id = KID_ACCESS_GRID_APPLE_PRIVACY,
        .ver = 0x01,
        .type = KEY_T_AES128,
        .data = {
            // 0x76, 0x76, 0x09, 0xED, 0x97, 0x33, 0xAF, 0x6C,
		    // 0x20, 0x74, 0x62, 0x30, 0xFB, 0x03, 0x7D, 0x19
            //6e369e1a479c14601d2ed20a4121a67d
            0x6E, 0x36, 0x9E, 0x1A, 0x47, 0x9C, 0x14, 0x60,
            0x1D, 0x2E, 0xD2, 0x0A, 0x41, 0x21, 0xA6, 0x7D
        },
    },
    .access_grid_apple_read = {
        .id = KID_ACCESS_GRID_APPLE_READ,
        .ver = 0x01,
        .type = KEY_T_AES128,
        .data = {
            // 0xB8, 0x58, 0xAB, 0x3A, 0xEA, 0x17, 0x2C, 0xFD,
		    // 0x47, 0xBE, 0xDE, 0x63, 0xE8, 0x33, 0x52, 0x0A
            //6e369e1a479c14601d2ed20a4121a67d
            0x6E, 0x36, 0x9E, 0x1A, 0x47, 0x9C, 0x14, 0x60,
            0x1D, 0x2E, 0xD2, 0x0A, 0x41, 0x21, 0xA6, 0x7D
        },
    },
};

/*
默认配置
*/
static const config_param_t cfg_param_default = {
    .apple_wallet = {
        .version = PARAM_VER_APPLE,
        .epc = {0x02, 0xC3, 0x02, 0x02, 0x02, 0x09, 0x01},
        .file_no = 0x01,
        .offset = 0,
        .length = 16,
        .format = 40,        
        .key_sets = {
            [0] = {
                .aid = {0x00, 0x1E, 0xA1},    // AID 小端
                .key_id = KID_APPLE_PRIV,
                .key_no = 0x00,
            },
            [1] = {
                .aid = {0x01, 0x1E, 0xA1},
                .key_id = KID_APPLE_CRED,
                .key_no = 0x00,
            },
	    },
    },
    .google_wallet = {
        .version = PARAM_VER_GOOGLE,
        .key_set = {
            .aid = {0xF5,0x32,0xF0},
            .key_id = KID_GOOGLE,
            .key_no = 0x01,
        },
        .file_no = 0x02,
        .df_name = {0xa0, 0x00, 0x00, 0x03, 0x96, 0x56, 0x43, 0x41, 0x03, 0xf5, 0x32, 0xf0, 0x00, 0x02, 0x09, 0x01},
    },
    .leaf = {
        .version = PARAM_VER_LEAF, 
        .key_set = {
            .aid = {0xDB, 0x1C, 0xF5},
            .key_id = KID_LEAF,
            .key_no = 0x01,
        },
        .file_no = 0x02,
    },
    .swiftlane = {
        .version = PARAM_VER_SWIFTLANE,
        // apple
        .epc = {0x02, 0xC3, 0x02, 0x02, 0x03, 0xFF, 0xFF},
        .awc_key_set = {
            .aid = {0xF5,0x69,0xA0},
            .key_id = KID_SW_AWC_APP,
            .key_no = 0x00,
        },
        .awc_file_no = 0,
        .awc_length = 5,
        //desfire
        .sdc_key_set = {
            .aid = {0xF5,0x67,0xA0},
            .key_id = KID_SW_SDC_READ,
            .key_no = 0x00,
        },
        .div = {0xE7,0x95,0xEB,0x10,0xBF,0xAA,0xD6,0x29,0x94,0x54,0x79,
            0x38,0xFB,0x0C,0xE4,0x6E,0x77,0x09,0x81,0x67},
        .sdc_file_no = 0,
        .sdc_length = 5,
    },
    .access_grid = {
        .version = PARAM_VER_ACCESS_GRID,
        .epc = {0x02, 0xC3, 0x02, 0x02, 0x02, 0x00, 0x00},
        //0xF56401
        .awc_privacy_key_set = {
            .aid = {0x01, 0x64, 0xF5},
            .key_id = KID_ACCESS_GRID_APPLE_PRIVACY,
            .key_no = 0x02,
        },
        .awc_read_key_set = {
            .aid = {0x01, 0x64, 0xF5},
            .key_id = KID_ACCESS_GRID_APPLE_READ,
            .key_no = 0x01,
        },
        .awc_file_no = 0,
        .awc_length = 22,
    },
};

// 声明更新标志，用于跟踪配置是否已更新
static uint8_t config_update_flag = 0;
static uint32_t config_update_delay_ms = 0;
static uint32_t config_update_tick = 0;
config_key_t config_key;
config_param_t config_param;
/*============================================================================================================*/
//加密
int config3_encrypt(uint8_t* data, uint16_t length, const uint8_t* key){
    uint8_t iv[16] = {0};
    uint16_t remain = length & (16-1);
    uint16_t enc_len;
    if(remain){
        data[length] = 0x80;
        memset(data + length + 1, 0, 16 - remain-1);
        enc_len = length + 16 - remain;
    }
    else{
        enc_len = length;
    }
    
    mbedtls_aes_context ctx;
    mbedtls_aes_init(&ctx);
    mbedtls_aes_setkey_enc(&ctx, key, 128);
    mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, enc_len, iv, data, data);    
    return enc_len;
}

int config3_decrypt(uint8_t* buffer, uint16_t length, const uint8_t* key){
    uint8_t iv[16] = {0};
    if(length & (16-1)){
        LOG2_ERR("length must be multiple of 16 bytes, length= %u", length);
        return -1;
    }
    mbedtls_aes_context ctx;
    mbedtls_aes_init(&ctx);
    mbedtls_aes_setkey_dec(&ctx, key, 128);
    mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, length, iv, buffer, buffer);    
    return 0;
}

static void config3_key_gen(uint8_t* key){
    uint32_t uid[4] = {0};
    BSP_GetUid(uid);    
    mbedtls_aes_context ctx;
    mbedtls_aes_init(&ctx);
    mbedtls_aes_setkey_enc(&ctx, root_key, 128);
    mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, (uint8_t*)uid, key);
}

static int config3_mac(const uint8_t *input, uint16_t length, const uint8_t*key, uint8_t *mac){
    uint8_t output[16];
    int ret;
    const mbedtls_cipher_info_t *cipher_info;
    
    cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
    ret = mbedtls_cipher_cmac(cipher_info, key, 128, input,
                                       length, output);
    if(!ret){
        memcpy(mac, output, 8);
    }
    else{
        LOG2_ERR("config3_mac error ret: %d", ret);
    }                                       
    return ret;
}


/*============================================================================================================*/
static uint16_t config_calc_crc16(const config_storage_t* store){
    // 计算CRC16校验和
    uint16_t length = store->length + sizeof(store->length) + sizeof(store->version);    
    return crc16((const uint8_t*)&store->version, length);
}
/*============================================================================================================*/
//获取默认密钥
static const key_t* key_factory_get(uint8_t id){
    // 根据传入的id值，返回对应的默认密钥
    switch (id)
    {
    case KID_KFR0:  return &factory_keys[0]; // 返回KID_KFR0对应的默认密钥
    case KID_KFR:   return &factory_keys[1]; // 返回KID_KFR对应的默认密钥
    case KID_KFM:   return &factory_keys[2]; // 返回KID_KFM对应的默认密钥
    default:
        break;
    }
    return NULL; // 如果id不匹配任何默认密钥，返回NULL
}
//获取密钥
static key_t* config_key_get(uint8_t id){
    // 根据传入的id值，返回对应的密钥存储位置
    switch (id)
    {
    // case KID_KFR0:  return &key_default[0];
    // case KID_KFR:   return &key_default[1];
    // case KID_KFM:   return &key_default[2];

    case KID_KMR:   return &config_key.kgm.kr; // 返回KID_KMR对应的制造商密钥
    case KID_KMM:   return &config_key.kgm.km; // 返回KID_KMM对应的制造商密钥
    case KID_KCR:   return &config_key.kgc.kr; // 返回KID_KCR对应的客户密钥
    case KID_KCM:   return &config_key.kgc.km; // 返回KID_KCM对应的客户密钥
    case KID_KUR:   return &config_key.kgu.kr; // 返回KID_KUR对应的用户密钥
    case KID_KUM:   return &config_key.kgu.km; // 返回KID_KUM对应的用户密钥
 
    case KID_APPLE_PRIV:    return &config_key.apple_keys[0]; // 返回KID_APPLE_PRIV对应的苹果密钥
    case KID_APPLE_CRED:    return &config_key.apple_keys[1]; // 返回KID_APPLE_CRED对应的苹果密钥

    case KID_GOOGLE:     return &config_key.google_key; // 返回KID_GOOGLE对应的谷歌密钥
    case KID_LEAF:     return &config_key.leaf_key; // 返回KID_LEAF对应的LEAF密钥
    case KID_SAMSUNG_PAY:     return &config_key.samsung_pay_key; // 返回KID_SAMSUNG_PAY对应的samsung pay密钥
    
    case KID_SW_AWC_APP: return &config_key.swiftlane_awc_app;
    case KID_SW_SDC_READ: return &config_key.swiftlane_sdc_read;

    case KID_ACCESS_GRID_APPLE_READ: return &config_key.access_grid_apple_read;
    case KID_ACCESS_GRID_APPLE_PRIVACY: return &config_key.access_grid_apple_privacy;

    default:
        break;
    }
    return NULL;
}

static int config_do_read(lfs_file_t* file, config_storage_t* cfg, uint16_t size){
    int err; 
    // 从文件中读取数据
    err = lfs_file_read(&lfs, file, cfg, sizeof(*cfg));
    if(err != sizeof(*cfg)){
        LOG2_ERR("lfs_file_read error: %d", err);        
        return err; 
    }
    if(cfg->length > (size - sizeof(*cfg))){
        LOG2_ERR("config file length error: %d", cfg->length);        
        return -1; // 如果读取的长度不正确，返回错误  
    }
    err = lfs_file_read(&lfs, file, cfg->data, cfg->length);
    if(err != cfg->length){
        LOG2_ERR("lfs_file_read error: %d", err);       
        return err; 
    }
    //检查CRC16校验和
    uint16_t crc = config_calc_crc16(cfg);
    if(crc != cfg->crc){
        LOG2_ERR("CRC16 error: %04x != %04x", crc, cfg->crc);
        return -1;
    }
    return 0; // 返回读取操作的结果
}

static int config_read(const char* file_name, config_storage_t* cfg, uint16_t size){
    lfs_file_t file;
    int err; 
    // 打开文件，以只读模式
    err = lfs_file_open(&lfs, &file, file_name, LFS_O_RDONLY);
    if(err){
        // 如果打开文件失败，记录错误日志并返回错误码
        LOG2_ERR("lfs_file_open error: %d", err);
        return err;
    }
    // 从文件中读取数据
    err = config_do_read(&file, cfg, size);
    // 关闭文件
    lfs_file_close(&lfs, &file);
    return err; // 返回读取操作的结果
}

static int config_write(const char* file_name, config_storage_t* cfg){
    lfs_file_t file;
    int err;
    
    // 打开文件，以读写模式，如果文件不存在则创建
    err = lfs_file_open(&lfs, &file, file_name, LFS_O_RDWR | LFS_O_CREAT);
    if(err){
        // 如果打开文件失败，记录错误日志并返回错误码
        LOG2_ERR("lfs_file_open error: %d", err);
        return -1;
    }
    cfg->crc = config_calc_crc16(cfg); // 计算CRC16校验和
    uint32_t size = sizeof(*cfg) + cfg->length; // 计算总大小
    // 将数据写入文件
    err = lfs_file_write(&lfs, &file, cfg, size); // 写入配置头部
    // 关闭文件
    lfs_file_close(&lfs, &file);
    if(err != size){
        LOG2_ERR("lfs_file_write error: %d", err);
        return -2;
    }
    return 0; // 返回写入操作的结果
}

static int config_key_init(void){ 
    int err;
    uint8_t update = 0;
    uint8_t buffer[CFG_KEY_ENC_MAC_SIZE];
    config_storage_t* cfg = (config_storage_t*)buffer;
    config_key_t* cfg_key = (config_key_t*)(buffer + sizeof(config_storage_t));
    memset(buffer, 0, sizeof(buffer));
    //读取配置文件
    err = config_read(key_file_name, cfg, sizeof(buffer));
    if(err){
        LOG2_ERR("config_read error: %d", err);
        // 如果读取配置文件失败，使用默认密钥初始化
        update = 1; // 使用默认密钥初始化
    }
    else{
        // 检查魔术数和版本号
        if(cfg->magic != config_key_magic){
            LOG2_ERR("config key magic");
            update = 1; // 使用默认密钥初始化
        }
        else{            
            uint8_t rmac[8];
            uint8_t mac[8] = {0};
            uint16_t enc_len = cfg->length - 8;
            memcpy(rmac, cfg->data + enc_len, 8);
            err = config3_mac(cfg->data, enc_len, store_key, mac);
            if(err || memcmp(mac, rmac, 8) != 0){
                LOG2_ERR("config key mac error");
                LOG2_BUF_ERR("rmac", rmac, 8);
                LOG2_BUF_ERR("mac", mac, 8);
                update = 1; // 使用默认密钥初始化
            }
            else{
                config3_decrypt(cfg->data, enc_len, store_key);
            }            
        }
    }    
    
    if(update){
        uint8_t mac[8] = {0};
        memset(buffer, 0, sizeof(buffer));
        // 如果读取配置文件失败，使用默认密钥初始化
        memcpy(cfg_key, &cfg_key_default, sizeof(config_key_t));
        cfg->magic = config_key_magic; // 设置魔术数
        cfg->version = CFG_VER_KEY; // 设置版本号
        cfg->length = sizeof(config_key_t); // 设置数据长度        
        uint16_t enc_len = config3_encrypt(cfg->data, cfg->length, store_key);
        cfg->length = enc_len;
        
        config3_mac(cfg->data, enc_len, store_key, mac);
        memcpy(cfg->data+enc_len, mac, sizeof(mac));
        cfg->length = enc_len + sizeof(mac);
        LOG2_BUF_INF("mac", mac, sizeof(mac));
        // 如果有更新，写入配置文件
        err = config_write(key_file_name, cfg);
        if(err){
            LOG2_ERR("config_write error: %d", err);
            return err;
        }
        memcpy(&config_key, &cfg_key_default, sizeof(config_key_t));
    }
    else{
        //如果版本升级
        if(cfg->version != CFG_VER_KEY){

            LOG2_WRN("config key version upgrade: %04X => %04X", cfg->version, CFG_VER_KEY);

            uint16_t enc_len = cfg->length - 8;
            uint16_t data_len = enc_len - 1;
            while(cfg->data[data_len] != 0x80){
                data_len--;
            }
            data_len--;
            //保留旧版本数据，其余默认
            memcpy(&config_key, &cfg_key_default, sizeof(config_key_t));
            if(data_len > sizeof(config_key_t)){
                data_len = sizeof(config_key_t);
            }
            memcpy(&config_key, cfg_key, data_len); // 将配置密钥复制到全局变量中
            //保存
            config_update_flag |= CFG_FLAG_UPDATE_KEY;
        }
        else{
            memcpy(&config_key, cfg_key, sizeof(config_key_t)); // 将配置密钥复制到全局变量中
        }        
    }
    
    return 0; // 返回成功
}

static int config_param_init(void){ 
    int err;
    uint8_t update = 0;
    uint8_t buffer[sizeof(config_storage_t) + sizeof(config_param_t)];
    config_storage_t* cfg = (config_storage_t*)buffer;
    config_param_t* cfg_param = (config_param_t*)(buffer + sizeof(config_storage_t));
    //初始化配置参数
    err = config_read(param_file_name, cfg, sizeof(buffer));
    if(err){
        LOG2_ERR("config_read error: %d", err);
        // 如果读取配置文件失败，使用默认配置参数初始化
        update = 1; // 使用默认配置参数初始化
    }
    else{
        // 检查魔术数和版本号
        if(cfg->magic != config_param_magic){
            LOG2_ERR("config param magic or version error");
            update = 1; // 使用默认配置参数初始化
        }
        else{
            // memcpy(cfg_param, cfg->data, sizeof(config_param_t)); // 将数据复制到配置参数结构体中
        }
    }
    
    if(update){
        // 如果读取配置文件失败，使用默认配置参数初始化
        memcpy(cfg_param, &cfg_param_default, sizeof(config_param_t));
        cfg->magic = config_param_magic; // 设置魔术数
        cfg->version = CFG_VER_PARAM; // 设置版本号
        cfg->length = sizeof(config_param_t); // 设置数据长度
        // 如果有更新，写入配置文件
        err = config_write(param_file_name, cfg);
        if(err){
            LOG2_ERR("config_write error: %d", err);
            return err;
        }
    }
    else{
        //如果版本升级
        if(cfg->version != CFG_VER_PARAM){
            LOG2_WRN("config param version upgrade: %04X => %04X", cfg->version, CFG_VER_PARAM);
            uint16_t data_len = cfg->length;
            memcpy(cfg_param, &cfg_param_default, sizeof(config_param_t));
            if(data_len >= sizeof(config_param_t)){
                data_len = sizeof(config_param_t);
            }
            memcpy(cfg_param, cfg->data, data_len);
            config_update_flag |= CFG_FLAG_UPDATE_PARAM;
        }
    }
    memcpy(&config_param, cfg_param, sizeof(config_param_t)); // 将配置参数复制到全局变量中
    return 0; // 返回成功
}

int config_sam_get_uid(uint8_t* uid){
    if(uid == NULL){
        return -1;
    }
    memcpy(uid, sam_uid, sizeof(sam_uid));
    return sizeof(sam_uid);
}

int config_sam_check_uid(uint8_t* uid, uint8_t ulen){
    if(uid == NULL){
        return -1;
    }
    if(memcmp(uid, sam_uid, ulen) == 0){
        return 0;
    }
    if(memcmp(sam_uid, sam_uid_default, sizeof(sam_uid_default)) == 0){
        return 1;
    }
    return -1;
}

int config_sam_set_uid(uint8_t* uid, uint8_t ulen){
    int err;
    if(uid == NULL){
        return -1;
    }
    if(memcmp(uid, sam_uid_default, sizeof(sam_uid_default)) == 0){
        return -1;
    }
    if(memcmp(uid, sam_uid, ulen) == 0){
        return 0;
    }
    memcpy(sam_uid, uid, ulen);
    uint8_t buffer[sizeof(config_storage_t) + sizeof(config_sam_t)];
    config_storage_t* cfg = (config_storage_t*)buffer;
    config_sam_t* cfg_sam = (config_sam_t*)(buffer + sizeof(config_storage_t));    
    cfg->magic = config_sam_magic; // 设置魔术数
    cfg->version = CFG_VER_SAM; // 设置版本号
    cfg->length = sizeof(config_sam_t); // 设置数据长度
    memcpy(cfg_sam->uid, uid, ulen);
    // 如果有更新，写入配置文件
    err = config_write(sam_file_name, cfg);
    if(err){
        LOG2_ERR("config_write error: %d", err);
        return err;
    }
    return 0;
}

static void config_sam_init(void){
    int err;
    
    uint8_t buffer[sizeof(config_storage_t) + sizeof(config_sam_t)];
    config_storage_t* cfg = (config_storage_t*)buffer;
    config_sam_t* cfg_sam = (config_sam_t*)(buffer + sizeof(config_storage_t));
    memset(cfg, 0, sizeof(config_storage_t));
    
    //初始化配置参数
    err = config_read(sam_file_name, cfg, sizeof(buffer));
    if(err){
        LOG2_ERR("config_read error: %d", err);
    }
    else{
        // 检查魔术数和版本号
        if(cfg->magic != config_sam_magic){
            LOG2_ERR("config sam magic or version error");
        }
        else{
            memcpy(sam_uid, cfg_sam->uid, sizeof(sam_uid));
        }
    }
}

int config3_init(void){
    LOG2_DBG("cfg init!");

    config3_key_gen(store_key);    
    // mount the filesystem
    int err = lfs_setup();
    if(err){
        LOG2_ERR("lfs_setup error: %d", err);
        return err;
    }
    //初始化配置SAM
    config_sam_init();
    //初始化配置参数
    config_param_init();
    //初始化密钥
    config_key_init();

    return 0;
}
// 获取密钥
int config3_get_key(uint8_t kid, key_t* key){
    const key_t* k;
    kid &= ~ KID_FLASH_MASK;
    // 如果id大于KID_KFM，从密钥存储中获取密钥
    if(kid > KID_KFM){
        k = config_key_get(kid);
    }
    // 否则，从默认密钥中获取密钥
    else{
        k = key_factory_get(kid);
    }
    
    // 如果获取的密钥为NULL，记录错误日志并返回错误码
    if(k == NULL){
        LOG2_ERR("key id error: %d", kid);
        return -1;
    }
    // 如果密钥类型为KEY_T_NONE，记录错误日志并返回错误码
    if(k->type == KEY_T_NONE){
        LOG2_ERR("key id: %d, type: %d", k->id, k->type);
        return -2;
    }
    // 将获取的密钥复制到传入的key指针指向的内存中
    memcpy(key, k, sizeof(key_t));
    return 0;
}

//设置密钥
int config3_set_key(uint8_t kid, const key_t* key) {
    kid &= ~ KID_FLASH_MASK;
    // 获取指定ID的密钥存储位置
    key_t* k = config_key_get(kid);
    // 如果获取失败，记录错误日志并返回错误码
    if (k == NULL) {
        LOG2_ERR("key id error: %02X", kid);
        return -1;
    }
    // 检测密钥是否更新
    if (memcmp(k, key, sizeof(key_t)) == 0) {
        // 如果密钥未更新，直接返回
        return 0; 
    }
    // 更新密钥
    memcpy(k, key, sizeof(key_t));
    // 设置更新标志
    config_update_flag |= CFG_FLAG_UPDATE_KEY;
    return 0;
}

// 保存配置
int config3_sync(void) {
    // 如果没有更新，直接返回
    if (config_update_flag == 0) {
        return 0;
    }
    if(config_update_delay_ms > 0){
        if(xTaskGetTickCount() - config_update_tick < config_update_delay_ms){
            return 0;
        }
        config_update_delay_ms = 0;
    }
    uint8_t flag = config_update_flag;
     // 清除更新标志
    config_update_flag = 0;
     
    int err = 0;

    if(flag & CFG_FLAG_UPDATE_KEY){
        // 如果更新标志包含密钥更新标志，写入密钥文件
        uint8_t *buffer = pvPortMalloc(CFG_KEY_ENC_MAC_SIZE);
        if(buffer == NULL){
            LOG2_ERR("pvPortMalloc error");
            return -1;
        }
        // uint8_t buffer[CFG_KEY_ENC_MAC_SIZE];
        config_storage_t* cfg = (config_storage_t*)buffer;
        config_key_t* cfg_key = (config_key_t*)(buffer + sizeof(config_storage_t));
        uint8_t mac[8] = {0};
        memset(buffer, 0, sizeof(CFG_KEY_ENC_MAC_SIZE));
        memcpy(cfg_key, &config_key, sizeof(config_key_t));
        cfg->magic = config_key_magic;
        cfg->version = CFG_VER_KEY;
        cfg->length = sizeof(config_key_t);
        uint16_t enc_len = config3_encrypt(cfg->data, cfg->length, store_key);
        config3_mac(cfg->data, enc_len, store_key, mac);
        memcpy(cfg->data+enc_len, mac, sizeof(mac));
        cfg->length = enc_len + sizeof(mac);
        err = config_write(key_file_name, cfg);
        vPortFree(buffer);
        if(err){
            LOG2_ERR("config_write key error: %d", err);
            return err;
        }
    }

    if(flag & CFG_FLAG_UPDATE_PARAM){
        // 如果更新标志包含参数更新标志，写入参数文件
        uint8_t *buffer = pvPortMalloc(sizeof(config_storage_t) + sizeof(config_param_t));
        if(buffer == NULL){
            LOG2_ERR("pvPortMalloc error");
            return -1;
        }
        // uint8_t buffer[sizeof(config_storage_t) + sizeof(config_param_t)];
        config_storage_t* cfg = (config_storage_t*)buffer;
        config_param_t* cfg_param = (config_param_t*)(buffer + sizeof(config_storage_t));
        memcpy(cfg_param, &config_param, sizeof(config_param_t));
        cfg->magic = config_param_magic;
        cfg->version = CFG_VER_PARAM;
        cfg->length = sizeof(config_param_t);
        err = config_write(param_file_name, cfg);
        vPortFree(buffer);
        if(err){
            LOG2_ERR("config_write param error: %d", err);
            return err;
        }
    }

    return err;
}

int config3_update_key(const key_t* key, uint8_t num){
    for(uint8_t i = 0; i < num; i++){
        config3_set_key(key[i].id, &key[i]);
    }
    return 0;
}

void config3_update(uint8_t flag){
    config_update_flag |= flag;
}

void config3_update_delay(uint32_t ms){
    config_update_delay_ms = ms;
    config_update_tick = xTaskGetTickCount();
}
